package sma.agents;

import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import javax.vecmath.Vector2d;

import ihm.AppliWindow;

import org.janusproject.kernel.address.Address;
import org.janusproject.kernel.agentsignal.QueuedSignalAdapter;
import org.janusproject.kernel.crio.core.GroupAddress;
import org.janusproject.kernel.status.Status;
import org.janusproject.kernel.status.StatusFactory;

import sma.agents.StandartAgent.GuiChannelImpl;
import sma.agents.bodies.MassCenterAgentBody;
import sma.agents.channels.DirectionChannel;
import sma.agents.listeners.DeleteListener;
import sma.agents.listeners.MoveGoalListener;
import sma.agents.listeners.MoveListener;
import sma.agents.listeners.DirectionListener;
import sma.environment.LocalEnvironment;
import sma.organizations.RealEnvironmentOrga;
import sma.organizations.roles.MassCenter;
import sma.organizations.signals.SendMoveSignal;
import sma.organizations.signals.SendDirectionSignal;
import appli.utils.Config;

/**
 * TODO : vérifier obsolescence de cette classe
 * Cette class est le centrer de graivté des agents de décision
 * @author Etienne Sainton
 * @since 0.1
 */
public class MassCenterAgent extends StandartAgent {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;


	/** 
	 * Le channel de discussion avec la GUI
	 */
	private DirectionChannel directionChannel;
	
	/**
	 * Create a local listener on the signals coming from the role itself.
	 */
	private QueuedSignalAdapter<SendDirectionSignal> privateDirectionSignals 
		= new QueuedSignalAdapter<SendDirectionSignal>(SendDirectionSignal.class);
	
	
	/**
	 * Constructeur. L'agent evolue maintenant dans un environnement.
	 * 
	 * @param _environment : environnement local
	 * @see LocalEnvironment
	 */
	public MassCenterAgent(LocalEnvironment _environment) {
		// On définit l'environnement :
		this.environment = _environment;

		// On vérifie l'implementation de la memoire
		//memory = getMemory();
		//assert (memory != null);

		// On lui affecte un body propre à son role :
		this.body = new MassCenterAgentBody();

		// Et on confirme
		if (Config.DEBUG == true)
			System.out.println("Agent MassCenter operationnel");
		
		getSignalEmitter().addSignalListener(this.privateDirectionSignals);
	}

	/**
	 * activate, Permet d'activer l'agent avant qu'il vive. Il prend pour role
	 * Goal. Par ailleurs des parametres de sortie s'afficheront en cas de mode
	 * debug.
	 * 
	 * @param parameters inutile de mettre quelque chose ici
	 */
	@Override
	public Status activate(Object... parameters) {
		super.init((JComponent) parameters[0]);
		System.out.println((JComponent) parameters[0]);
		
		directionChannel = new DirectionChannelImpl();
		directionChannel.addDirectionListener((DirectionListener) parameters[1]);
				
		
		
		if (Config.DEBUG == true)
			System.out.println("Agent Goal activé");

		// Recuperation de l'adresse du groupe Voiture
		GroupAddress RealEnvirmnent = getOrCreateGroup(RealEnvironmentOrga.class);

		// Affectation du role de Goal dans le groupe Voiture
		if (requestRole(MassCenter.class, RealEnvirmnent, this.environment, this.body, (Double) parameters[2])) {
			if (Config.DEBUG == true)
				System.out.println("Agent MassCenter appartient " +
						"au role MassCenter dans le groupe " +
						"RealEnvirmnent");
			return StatusFactory.ok(this);
		} else if (Config.DEBUG == true)
			System.out.println("L'agent MassCenter ne peut pas " +
					"appartenir au role MassCenter dans le" +
					" groupe RealEnvirmnent...");

		return StatusFactory.cancel(this);
	}
	
	@Override
	public Status live() {
		
		// Recuperons les derniers mouvements en memoire
		{
			SendDirectionSignal sig;
			sig = this.privateDirectionSignals.getFirstAvailableSignal();
			while (sig != null) {
				
				directionChannel.moveVehicule(sig.getPosition());
				
				sig = this.privateDirectionSignals.getFirstAvailableSignal();	
			}
		}
		
		super.live();
		
		return StatusFactory.ok(this);
	}
	

	/**
	 * Mort de l'agent
	 */
	@Override
	public Status end() {
		if (Config.DEBUG == true)
			print("AgentGravity : Je suis mort....");
		return StatusFactory.ok(this);
	}
	
	/**
	 * @return the guiChannel
	 */
	public DirectionChannel getPositionChannel() {
		return directionChannel;
	}
	
	/**
	 * 
	 * @author Arnaud Schaeffer
	 *
	 */
	public class DirectionChannelImpl implements DirectionChannel {

		@Override
		public Address getChannelOwner() {
			// TODO Auto-generated method stub
			return null;
		}


		@Override
		public void moveVehicule(Vector2d pos) {
			
			/*DirectionListener[] list = getEventListeners(DirectionListener.class);

			for (DirectionListener listener : list) {
				listener.onMoveVehicule(pos);
			}*/
			
		}

		@Override
		public void addDirectionListener(DirectionListener listener) {
			MassCenterAgent.this.addEventListener(DirectionListener.class, listener);				
		}


		@Override
		public void removeDirectionListener(DirectionListener listener) {
			MassCenterAgent.this.removeEventListener(DirectionListener.class, listener);			
		}


	}

}